﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace Micro.Core.ApiConsumer.Context
{
    /// <summary>
    /// 接口上下文类
    /// </summary>
    public class ApiActionContext
    {
        /// <summary>
        /// 接口Action特性描述
        /// </summary>
        public ApiActionDescriptor ActionDescriptor { get; set; }

        /// <summary>
        /// 接口请求对象实体
        /// </summary>
        public HttpRequest Request { get; set; }

        /// <summary>
        /// 执行http请求
        /// </summary>
        /// <returns></returns>
        public string Execute()
        {
            foreach (var actionAttribute in ActionDescriptor.Attributes)
            {
                actionAttribute.Compose(Request);
            }

            foreach (var parameter in ActionDescriptor.Parameters)
            {
                parameter.ParameterAttribute.Compose(Request, parameter);
            }
            var result = Send(Request);
            return result;
        }

        /// <summary>
        /// 发起请求
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public string Send(HttpRequest request)
        {
            Stream instream = null;
            StreamReader sr;
            Stream outstream = null;
            HttpWebResponse response = null;
            HttpWebRequest webRequest = null;
            Encoding encoding = Encoding.UTF8;
            try
            {
                System.GC.Collect();
                // 准备请求...
                webRequest = (HttpWebRequest)WebRequest.Create(request.Url);
                //webRequest.ServicePoint.ConnectionLimit = int.MaxValue;
                webRequest.KeepAlive = false;
                webRequest.ServicePoint.Expect100Continue = false;
                webRequest.Proxy = null;
                webRequest.Method = request.Method;
                if (request.Method.ToUpper().Equals("POST"))
                {
                    byte[] payload = encoding.GetBytes(JsonConvert.SerializeObject(request.Data));
                    webRequest.ContentType = "application/json";
                    webRequest.ContentLength = payload.Length;
                    outstream = webRequest.GetRequestStream();
                    outstream.Write(payload, 0, payload.Length);
                    outstream.Close();
                    outstream = null;
                }

                //发送请求并获取相应回应数据
                response = webRequest.GetResponse() as HttpWebResponse;

                //直到request.GetResponse()程序才开始向目标网页发送Post请求
                instream = response.GetResponseStream();
                sr = new StreamReader(instream, encoding);
                string content = sr.ReadToEnd();
                response.Close();
                response = null;
                return content;
            }
            catch (Exception e)
            {
                if (instream != null) instream.Close();
                if (outstream != null) outstream.Close();
                if (response != null) response.Close();
                if (webRequest != null) webRequest.Abort();
                throw e;
            }
        }
    }
}
